package evolution.stop;

import evolution.algorithm.CoevolutionAlgorithm;
import evolution.algorithm.Iterative;
import evolution.individual.Individual;
import evolution.problem.OptimizationProblem;

public class EpsilonTimeStopCondition extends TimeStopCondition {
	private double epsilon = 0;
	private OptimizationProblem problem;

	public double getEpsilon() {
		return epsilon;
	}

	public void setEpsilon(double epsilon) {
		this.epsilon = epsilon;
	}

	@Override
	public boolean shouldStop(Iterative algorithm) {
		boolean timeOver = super.shouldStop(algorithm);
		if (timeOver) {
			return true;
		}

		CoevolutionAlgorithm coevAlg = (CoevolutionAlgorithm) algorithm;
		Individual bestIndividual = coevAlg.getBestIndividual();
		double value = bestIndividual.getFitnessFunction().convertToRealValue(
				bestIndividual.getFitness());

		if (problem == null) {
			problem = coevAlg.getEvolutionaryAlghorithmEpochRunners().get(0)
					.getEvolutionaryAlghorithm().getOptimizationProblem();
		}

		if (Math.abs(value - problem.getOptimumValue()) < epsilon) {
			return true;
		}

		return false;
	}
}
